複習一下 👉 現在獲取了使用者的資訊要開始交換 SDP
,需要完成下圖1~8個步驟,並且創建的offer、answer 需放在 Slignaling Server
也就是前幾篇創建的 firestore db 中,雙方都必須 setLocalDescription
、setRemoteDescription
。
🚀可以複習 [Day10] RTCPeerConnection - SDP 與建立連線
iceServers
是一個用於設定 WebRTC ICE server 的陣列。這個陣列包括 STUN 和 TURN 伺服器的資訊,這邊只使用 google 提供免費的 STUN server 。
iceCandidatePoolSize
ICE 協商過程中生成的 ICE 候選人的數量。根據應用程序的需求和性能考慮來配置。較大可能會增加成功建立連接的機會,但也會增加網絡流量和運算成本。
const configuration = {
iceServers: [
{
urls: ["stun:stun1.l.google.com:19302", "stun:stun2.l.google.com:19302"]
}
],
iceCandidatePoolSize: 10
};
createRoom
& joinRoom
的使用者接需要創建一個新的 RTCPeerConnection
localStream
是一個 array 包含視訊 + 音訊使用 forEach
獲取後加入至 pc
async function createRoom() {
// 創建一個新的 RTCPeerConnection
if (!localStream.current) {
alert('請先開啟視訊及麥克風');
return;
}
const pc = new RTCPeerConnection(configuration);
// 創建房間
const roomRef = await addDoc(collection(db, "rooms"), {});
const roomId = roomRef.id;
window.alert(roomId);
// 將 localStream 中的媒體加入至 pc 中
localStream.current.getTracks().forEach((track) => {
pc.addTrack(track, localStream.current);
});
// 1. 建立 offer
const offer = await pc.createOffer();
const roomWithOffer = {
offer: {
type: offer.type,
sdp: offer.sdp
}
};
// 2. offer 設定 setLocalDescription,放在 db 中交換
await pc.setLocalDescription(offer);
await setDoc(roomRef, roomWithOffer);
// 7. 監聽並收到 Answer
// 8. Answer 設定 RemoteDescription
onSnapshot(roomRef, async (snapshot) => {
const data = snapshot.data();
if (data?.answer && !pc.currentRemoteDescription) {
const rtcSessionDescription = new RTCSessionDescription(data.answer);
await pc.setRemoteDescription(rtcSessionDescription);
}
});
}
async function joinRoom(roomId) {
if (!localStream.current) {
alert('請先開啟視訊及麥克風');
return;
}
const roomRef = doc(db, "rooms", roomId);
const roomSnapshot = await getDoc(roomRef);
if (roomSnapshot.exists() === false) {
alert('您輸入的聊天室 id 不存在');
return;
}
// 創建一個新的 RTCPeerConnection
const pc = new RTCPeerConnection(configuration);
localStream.current.getTracks().forEach((track) => {
pc.addTrack(track, localStream.current);
});
// 3. 尋找 db 中的 offer
// 4. offer 設定 RemoteDescription
const offer = roomSnapshot.data()?.offer;
await pc.setRemoteDescription(new RTCSessionDescription(offer));
// 5. 建立 Answer
// 6. Answer 設定 LocalDescription,放在 db 中交換
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
const roomWithAnswer = {
answer: {
type: answer.type,
sdp: answer.sdp
}
};
await updateDoc(roomRef, roomWithAnswer);
}
此時於createRoom
8. Answer 設定 RemoteDescription console.log(pc)
可以看到 localDescription
、remoteDescription
這篇文章做了 SDP
的交換過程可以在程式碼的註解看到步驟,若有順利交換就可以在 console
中發現 local
及 remote
皆有 SDP
資訊,此時也可以在 firestore db 中看到setDoc
、updateDoc
時增加的資訊。